package torcs.danielpd.SANE;

import java.util.Random;

import ecprac.ea.abstracts.AbstractEA;
import ecprac.ea.abstracts.DriversUtils;
import ecprac.ea.abstracts.AbstractRace.DefaultTracks;

public class MyEA extends AbstractEA {
	private static final long serialVersionUID = 1L;
	Random r = new Random(8);
	int evals = 0;
	
	// Neural network hidden layer
	public static int hiddenLayerSize = 12;
	public static int inputLayerSize = 5;
	public static int outputLayerSize = 2;
	
	// Population
	DriverGenome[] population = new DriverGenome[10];
	
	// Fitness
	int[] fitness = new int[population.length];
	
	public void run() {
		run(false);
	}
	
	@Override
	public void run(boolean continue_from_last_checkpoint) {
		
		if (!continue_from_last_checkpoint) {
			initialize();
			evaluatePopulation();
		}
		
		while (evals < 5000) {
			evaluatePopulation();
			
			// create a checkpoint 
			// this allows you to continue this run later
			DriversUtils.createCheckpoint(this);
			
			System.out.println("Evaluations: " + evals);
		}
	}

	public void initialize() {
		for (int dg = 0; dg < population.length; dg++) {
			population[dg] = new DriverGenome(hiddenLayerSize);
			population[dg].initialize();
			fitness[dg] = 0;
		}
	}
	
	public void evaluatePopulation() {
		MyRace race = new MyRace();
		race.setTrack( DefaultTracks.getTrack(r.nextInt(4)) );
		race.laps = 2;
		// Run the race, fitness = rank
		// The GUI is set to true, for speedup set withGUI to false
		fitness = race.runRace(population, true);
		
		// Increment the number of evaluations
		evals+=population.length;
		
		// Save the best genome from the population
		for(int i=0; i<population.length; i++){
			if(fitness[i] == 1){
				DriversUtils.storeGenome(population[i]);
			}
		}	
	}
	
	/**
	 * @param args
	 */
	public static void main(String[] args) {

		MyEA ea = new MyEA();
		ea.run(false);
		
		
	}
}
